package org.heart.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import dev.langchain4j.memory.ChatMemory;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.model.openai.OpenAiChatModel;
import lombok.extern.slf4j.Slf4j;
import org.heart.common.CommonResult;
import org.heart.entity.resp.DetailsDataResp;
import org.heart.entity.resp.IndexDatResp;
import org.heart.service.CommonService;
import org.heart.thirdService.AIServiceAPI.service.AisServices;
import org.heart.thirdService.hefengAPI.req.DailyWeather;
import org.heart.thirdService.hefengAPI.req.HourlyWeather;
import org.heart.thirdService.hefengAPI.req.Location;
import org.heart.thirdService.hefengAPI.req.NowWeather;
import org.heart.thirdService.hefengAPI.service.HeFengApiService;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

@RequestMapping("/api")
@RestController
@Slf4j
public class CommonController {


    @Resource
    private HeFengApiService heFengApiService;

    @Resource
    private CommonService commonService;

    @Resource
    private AisServices aisServices;

    @Resource
    private OpenAiChatModel openAiChatModel;

    /**
     * 请求主页天气数据
     */
    @GetMapping("/getIndexData")
    public CommonResult<IndexDatResp> getIndexData(@RequestParam(value = "latitude",required = false) String latitude,
                                                   @RequestParam(value = "longitude",required = false) String longitude){

       log.info("请求参数：latitude = {}：longitude= {}",latitude,longitude);

        if(ObjectUtils.isNull(latitude) || ObjectUtils.isNull(longitude)){
            return CommonResult.errorResponse("接口：【getIndexData】经纬度不能为空！");
        }

        ChatMemory chatMemory = MessageWindowChatMemory.withMaxMessages(10);

        AisServices assistant = dev.langchain4j.service.AiServices.builder(AisServices.class)
                .chatModel(openAiChatModel)
                .chatMemory(chatMemory)
                .build();

        /**
         * 获取用户地址
         */
        Location address = commonService.getUserAddress(latitude,longitude);

        log.info("用户地址为：{}",address);
        NowWeather nowWeather = new NowWeather();

        nowWeather = heFengApiService.getNowWeather(address.getId());

        if(ObjectUtils.isNull(nowWeather)){
            log.info("请求实时天气信息：{}，请求失败",nowWeather);
            return CommonResult.errorResponse("请求失败!");
        }

        List<DailyWeather> weatherList = heFengApiService.get7DayWeather(address.getId());

        if(ObjectUtils.isNull(weatherList)){
            log.info("请求天气预报信息：{}，请求失败！",nowWeather);
            return CommonResult.errorResponse("请求失败!");
        }

        IndexDatResp indexDatResp = new IndexDatResp();
        // 查询 天气信息（当天）
        BeanUtil.copyProperties(nowWeather, indexDatResp);

        // 查询 天气预报信息（七天）
        indexDatResp.setWeatherList(weatherList);

        log.info("查询主页天气数据情况：{}",indexDatResp);

        return CommonResult.successResponse(indexDatResp);
    }

    /**
     * 获取首页-天气温馨提醒
     */
    @PostMapping("/getIndexWxtx")
    public CommonResult<String> getIndexWxtx(@RequestBody IndexDatResp indexDatResp){

        String aiMessage = buildTodayWeatherDescription(indexDatResp);

        ChatMemory chatMemory = MessageWindowChatMemory.withMaxMessages(10);

        AisServices assistant = dev.langchain4j.service.AiServices.builder(AisServices.class)
                .chatModel(openAiChatModel)
                .chatMemory(chatMemory)
                .build();

        String warmReminder = assistant.getWarmReminder(aiMessage);

        return CommonResult.successResponse(warmReminder);
    }

    /**
     * 获取首页-天气温馨一言
     */
    @PostMapping("/getIndexWxyy")
    public CommonResult<String> getIndexWxyy(@RequestBody IndexDatResp indexDatResp){

        String aiMessage = buildTodayWeatherDescription(indexDatResp);

        ChatMemory chatMemory = MessageWindowChatMemory.withMaxMessages(10);

        AisServices assistant = dev.langchain4j.service.AiServices.builder(AisServices.class)
                .chatModel(openAiChatModel)
                .chatMemory(chatMemory)
                .build();

        String warmReminder = assistant.getAWarmWord(aiMessage);

        return CommonResult.successResponse(warmReminder);
    }

    /**
     * 获取请求天气数据（详情）
     */
    @GetMapping("/getWeatherDetails")
    public CommonResult<DetailsDataResp> getWeatherDetails(@RequestParam(value = "latitude",required = false) String latitude,
                                                           @RequestParam(value = "longitude",required = false) String longitude){


        if(ObjectUtils.isNull(latitude) || ObjectUtils.isNull(longitude)){
            return CommonResult.errorResponse("接口：【getIndexData】经纬度不能为空！");
        }

        ChatMemory chatMemory = MessageWindowChatMemory.withMaxMessages(10);

        AisServices assistant = dev.langchain4j.service.AiServices.builder(AisServices.class)
                .chatModel(openAiChatModel)
                .chatMemory(chatMemory)
                .build();

        /**
         * 获取用户地址
         */
        Location address = commonService.getUserAddress(latitude,longitude);

        log.info("用户地址为：{}",address);

        NowWeather nowWeather = heFengApiService.getNowWeather(address.getId());

        if(ObjectUtils.isNull(nowWeather)){
            log.info("请求实时天气信息：{}，请求失败",nowWeather);
            return CommonResult.errorResponse("请求失败!");
        }


        List<HourlyWeather> list = heFengApiService.getHourDuanWeather(address.getId());

        log.info("查询最近六小时时段数据为：{}",list);

        //获取健康建议
        String healthAdvice =  assistant.getHealthAdvice(nowWeather.getText());

        DetailsDataResp resp = new DetailsDataResp();
        BeanUtils.copyProperties(nowWeather,resp);
        resp.setHealthAdvice(healthAdvice);
        if(ObjectUtil.isNotEmpty(list)){
            resp.setSixHourWeatherTrend(convertHourlyWeather(list));
        }

        resp.setAddress(address.getAdm1()+'-'+address.getAdm2()+'-'+address.getName());

        return CommonResult.successResponse(resp);
    }

    public List<Map<String, String>> convertHourlyWeather(List<HourlyWeather> hourlyList) {
        List<Map<String, String>> resultList = new ArrayList<>();

        if (hourlyList == null) {
            return resultList;
        }

        DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("HH:mm");

        for (HourlyWeather hw : hourlyList) {
            Map<String, String> map = new HashMap<>();

            // 格式化 fxTime
            String formattedTime = "";
            try {
                OffsetDateTime odt = OffsetDateTime.parse(hw.getFxTime());
                formattedTime = odt.format(outputFormatter);
            } catch (Exception e) {
                formattedTime = hw.getFxTime(); // 解析失败时使用原始值
            }
            map.put("fxTime", formattedTime);
            map.put("temp", hw.getTemp());
            resultList.add(map);
        }

        return resultList;
    }

    /**
     * 获取首页天气提示词
     */
    public String buildTodayWeatherDescription(IndexDatResp data) {
        StringBuilder sb = new StringBuilder();

        sb.append("根据 ").append(" 今日天气情况：\n");
        sb.append("当前天气：").append(data.getText()).append("，气温 ").append(data.getTemp()).append("℃，");
        sb.append("体感温度 ").append(data.getFeelsLike()).append("℃，");
        sb.append("湿度 ").append(data.getHumidity()).append("%，");
        sb.append("风力 ").append(data.getWindScale()).append("级，风速 ").append(data.getWindSpeed()).append(" km/h。\n");

        if (data.getWarmReminder() != null && !data.getWarmReminder().isBlank()) {
            sb.append("温馨提醒：").append(data.getWarmReminder()).append("\n");
        }

        if (data.getAWarmWord() != null && !data.getAWarmWord().isBlank()) {
            sb.append("今日寄语：").append(data.getAWarmWord()).append("\n");
        }

        return sb.toString();
    }
}
